package comm

import (
	"bytes"
	"crypto/md5"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"math/rand"
	"net/http"
	"runtime"
	"strconv"
	"strings"
)

const (
	COST_CPU_WARNING = 100 //毫秒
	DAY_SECOND       = 86400

	//0:作废 1:白 2:黑 7:优质用户
	WB_USER_WHITE = 1
	WB_USER_BLACK = 2
	WB_USER_GRADE = 7
)

const (
	//功能配置ID 与 function.xlsx对应
	FUNC_FBD_REDPACKAGE = 6601 //禁止权益兑换
)

var (
	RedPackageMd5 = "s8fJyNg6rHu9kIdafhb55fgyoKv3Ymji" //与gamebox转账交互md5
	RedPackageUrl = ""                                 //conf.Server.GameBoxSer.HttpAddr + "/sys/red_package"
)

func RandChoice(rate []uint32) int {
	total := uint32(0)
	for _, r := range rate {
		total += r
	}

	r := uint32(rand.Int31n(int32(total)))
	for i, v := range rate {
		if r < v {
			return i
		}
		r -= v
	}
	//error
	log.Printf("rate pro is outside: %d", r)
	return -1
}

func Random(min, max int) int {
	return rand.Intn(max-min) + min
}

// 输出堆栈
func PStack(vs ...bool) {
	if len(vs) == 0 {
		return
	}
	for _, v := range vs {
		if !v {
			return
		}
	}
	var buf [2 << 10]byte
	log.Println(string(buf[:runtime.Stack(buf[:], true)]))
}

// 修改字符串某个位置的值
func SetRune(pv *string, i int, v rune) {
	if i >= len(*pv) {
		return
	}
	pvt := []rune(*pv)
	pvt[i] = v
	*pv = string(pvt)
}

func ParseIp(rawIp string) string {
	i := strings.LastIndex(rawIp, ":")
	if i >= 0 {
		rawIp = rawIp[0:i]
		if rawIp == "[::1]" || rawIp == "::1" {
			rawIp = "127.0.0.1"
		}
	}
	return rawIp
}

//==============================================================================================
//==============================================================================================

type (
	Int interface {
		int | int32 | int64
	}
	Uint interface {
		uint | uint32 | uint64
	}
	Float interface {
		float32 | float64
	}
)

func Min[T Int | Uint | Float](a, b T) T {
	if a < b {
		return a
	}
	return b
}

func Max[T Int | Uint | Float](a, b T) T {
	if a > b {
		return a
	}
	return b
}

func LogInfo(format string, a ...interface{}) {
	if true {
		log.Printf(format, a...)
	}
}
func Println(a ...any) {
	if true {
		fmt.Printf(GetYYMMDDHHmmss() + "  ")
		fmt.Println(a...)
	}
}
func Printf(fm string, a ...any) {
	if true {
		fmt.Printf(GetYYMMDDHHmmss() + "  ")
		fmt.Printf(fm, a...)
	}
}

//==============================================================================================
//==============================================================================================

func MakeHashCode(data string) string {
	h := md5.New()
	//fmt.Println("md5 h:", h)
	io.WriteString(h, data)
	sum := h.Sum(nil)
	str := hex.EncodeToString(sum[:])
	log.Printf("hash code %s->%s", data, str)
	return str
}

// 获取协程ID
func GetGid() (gid uint64) {
	b := make([]byte, 64)
	b = b[:runtime.Stack(b, false)]
	b = bytes.TrimPrefix(b, []byte("goroutine "))
	b = b[:bytes.IndexByte(b, ' ')]
	n, err := strconv.ParseUint(string(b), 10, 64)
	if err != nil {
		panic(err)
	}
	return n
}

// post(json)
func HttpPost(request any, url string) (*http.Response, error) {
	msData, err := json.Marshal(request)
	if err != nil {
		return nil, fmt.Errorf("marshal err:%v", err)
	}

	req, err := http.NewRequest("POST", url, strings.NewReader(string(msData)))
	if err != nil {
		return nil, fmt.Errorf("newRequest err:%v", err)
	}
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{}
	return client.Do(req)
}

func HttpGet(url, reqParam string) (*http.Response, error) {
	reqUrl := url + reqParam
	req, err := http.NewRequest("GET", reqUrl, nil) //strings.NewReader(reqParam)
	if err != nil {
		return nil, fmt.Errorf("newRequest err:%+v", err)
	}
	// 设置请求头信息
	//req.Header.Add("Accept-Encoding", "gzip, deflate, br")

	// 发送请求
	client := http.DefaultClient
	return client.Do(req)
}
